﻿#if UNITY_EDITOR
using System;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
/// <summary>
/// 编译扩展
/// </summary>
public static class ESF_CompilerExtend
{
    #region Cast 将指定Object转成T类型对象
    /// <summary>
    /// 将指定Object转成T类型对象
    /// </summary>
    /// <typeparam name="T">要转换的对象类型</typeparam>
    /// <param name="_self">数据源</param>
    /// <param name="_templete">对象模板</param>
    /// <returns>对象</returns>
    public static T Cast<T>(this object _self, T _templete)
    {
        return (T)_self;
    }
    #endregion

    #region EncodeToJson 将指定字符串编码为Json格式
    /// <summary>
    /// 将指定字符串编码为Json格式
    /// </summary>
    /// <param name="_string">要编码的字符串</param>
    /// <returns>编码为Json格式的字符串</returns>
    public static string EncodeToJson(this string _value)
    {
        return _value.EncodeToJson(false);
    }

    /// <summary>
    /// 将指定字符串编码为Json格式
    /// </summary>
    /// <param name="_string">要编码的字符串</param>
    /// <param name="_isTransChinese">是否编码中文</param>
    /// <returns>编码为Json格式的字符串</returns>
    public static string EncodeToJson(this string _value, bool _isTransChinese)
    {
        char[] hex_seq = new char[4];
        TextWriter writer = new StringWriter();
        writer.Write('"');

        int n = _value.Length;
        for (int i = 0; i < n; i++)
        {
            switch (_value[i])
            {
                case '\n':
                    writer.Write("\\n");
                    continue;

                case '\r':
                    writer.Write("\\r");
                    continue;

                case '\t':
                    writer.Write("\\t");
                    continue;

                case '"':
                case '\\':
                    writer.Write('\\');
                    writer.Write(_value[i]);
                    continue;

                case '\f':
                    writer.Write("\\f");
                    continue;

                case '\b':
                    writer.Write("\\b");
                    continue;
            }

            if ((int)_value[i] >= 32 && (int)_value[i] <= 126)
            {
                writer.Write(_value[i]);
                continue;
            }

            // Default, turn into a \uXXXX sequence
            if (!_isTransChinese)
            {
                writer.Write(_value[i]);
            }
            else
            {
                OnIntToHex((int)_value[i], hex_seq);
                writer.Write("\\u");
                writer.Write(hex_seq);
            }
        }

        writer.Write('"');
        return writer.ToString();
    }

    /// <summary>
    /// IntToHex
    /// </summary>
    /// <param name="_ascii">asc码</param>
    /// <param name="_hex_seq">十六进制序列</param>
    static void OnIntToHex(int _ascii, char[] _hex_seq)
    {
        int num = 0;
        for (int i = 0; i < 4; i++)
        {
            num = _ascii % 16;
            if (num < 10)
            {
                _hex_seq[3 - i] = (char)('0' + num);
            }
            else
            {
                _hex_seq[3 - i] = (char)('A' + (num - 10));
            }
            _ascii >>= 4;
        }
    }
    #endregion

    #region IsAnonymousType 类型是否是匿名类型
    /// <summary>
    /// 类型是否是匿名类型
    /// </summary>
    /// <param name="type">类型</param>
    /// <returns>true:匿名类型,false:非匿名类型</returns>
    public static bool IsAnonymousType(this Type type)
    {
        if (!type.IsGenericType)
        {
            return false;
        }
        if ((type.Attributes & TypeAttributes.NotPublic) != TypeAttributes.NotPublic)
        {
            return false;
        }
        if (!Attribute.IsDefined(type, typeof(CompilerGeneratedAttribute), false))
        {
            return false;
        }
        return type.Name.Contains("AnonymousType");
    }
    #endregion

    #region CompilerCSharp 编译CSharp代码
    /// <summary>
    /// 编译CSharp代码
    /// </summary>
    /// <param name="_codeTemplete">代码模板</param>
    /// <param name="_data">数据</param>
    /// <returns>代码</returns>
    public static string CompilerCSharp<T>(this string _codeTemplete, T _data)
    {
        return ESF_CSharpCompiler.Compiler(_codeTemplete, _data);
    }

    /// <summary>
    /// 编译CSharp代码执行静态方法
    /// </summary>
    /// <param name="_codeTemplete">代码模板</param>
    /// <param name="_className">类名</param>
    /// <param name="_methodName">静态方法名</param>
    /// <param name="_methodParameters">方法参数</param>
    /// <returns>方法返回值</returns>
    public static object CompilerInvokeStaticMethod(this string _codeTemplete, string _className, string _methodName, object[] _methodParameters)
    {
        return ESF_CSharpCompiler.CompilerInvokeStaticMethod(_codeTemplete, _className, _methodName, _methodParameters);
    }
    #endregion
}
#endif
